種内密度効果とロジスティック方程式

ロジステック方程式とは、オランダの数理生物学者Verhulst(1838)が考案した人口増加の方程式で、

\(\frac{dN}{dt}=\lambda N (1-\frac{N}{K})\)

で表される。\(\lambda\)は単位時間当たり、一匹あたりの増殖力で、\(\frac{dN}{dt}=\lambda N\)であれば、単純に上限なく鼠算的(指数関数的に)増殖を続けるが、個体の数が多くなってくると、互いに干渉しあったり、エサ資源を争ったり、居住空間を争ったりするようになる。これを種内密度効果と呼ぶ。ロジスティック方程式では、環境収容力\(K\)と呼ばれる定数まで増殖力が段々とゼロに近づき、これを超えると密度を抑える方向に向かう。

ロジスティック方程式は、解析的に解いて時間の関数\(N(t)\)として定式化できる。

\(N(t)=\frac{K}{1+\frac{(K-N(0)e^{-rt})}{N(0)}}\)

種内密度効果の他に、天候などの環境影響、農薬散布の影響、天敵など食う食われるものの関係、作物の成長度合いなど、色々な増殖・死亡にまつわる関係式を組み合わせることによって個体群モデルは作成される。様々な影響のモデル化については嶋田ら(2005)を参考にして欲しい。

ここでは、微分方程式の形のロジスティック方程式を使って数値解を求めてみる。この数値解を求める方法であれば、解析的に解けない個体群モデル(微分方程式)についてもその挙動をシミュレーションすることはできる。

*嶋田正和, 山村則男, 粕谷英一, 伊藤嘉昭. 2005. 動物生態学 新版. 海遊舎.

## install.packages("deSolve")  ## 常微分方程式・微分代数方程式・時間遅付微分方程式が扱える汎用ライブラリ
library(deSolve)

# 初期値
state <- c(N = 4)
# ロジスティック方程式のパラメタ
parameters <- c(lambda = 1.2, K = 100) 
# シミュレーションを実行する時間間隔
times <- seq(0, 100, by = 0.5)

## ロジスティック方程式の定義
logistic <- function(t, state, parameters){  
  # tはこの関数の中では使わないが時間に関する微分方程式なので必要?
  # わかりやすいようにパラメタ名を受け渡しておく
  lambda = parameters[1];
  K = parameters[2];
  N = state[1];
  dN <- lambda*N*(1-N/K)
  return(list(dN))  ## リストを返すのがdeSolveのお作法
}

## 数値解を求める=シミュレーション、定義した初期値、パラメタ、時間間隔、方程式を代入
out <- ode(y = state, parms = parameters, times = times, func = logistic)

## プロット
plot(out[,"time"], out[,"N"], type="l", xlab="経過時間", ylab="人口")

ロジスティック差分方程式

微分方程式では瞬間的な出生と死亡が記述されるが、害虫のように世代がはっきりしている生物に対しては、世代ごとの逐次計算として表現される差分方程式(高校の数学B数列のこと)の方が直感的にわかりやすい。Verhulstのロジスティック方程式を強制的に差分化すると、

\(N_{t+1}=N_t+\lambda N_t (1-\frac{N_t}{K})\)

ここではもっと単純化して\(N_{t+1}=aN_t(1-N_t)\)について考える。

#簡単な差分ロジスティックモデル(表示までさせる)
sim<- function(N0, a, times) {
  # times個のベクトルを受け皿にする
    N <- numeric(times);
    # 初期値の代入
    N[1]<-N0;
    # 2時点~times時点へのシミュレーション
    for(i in 1:(times-1)) {
        N[i+1]<-a*N[i]*(1-N[i])
    }
    # 表示
    plot(1:times, N, type="l", xlab="経過時間", ylab="人口")
}

# 0<a<1の時
sim(0.3, 0.4, 50); title("常に絶滅")
# 1<a<3の時
sim(0.3, 2.4, 50); title("安定平衡")
# 3<a<3.449...の時
sim(0.3, 3.2, 50); title("振動")
# 3.5700..<a<4の時
sim(0.3, 3.7, 50); title("カオス")

どうしてパラメタ\(a\)の値が大きくなると微分方程式バージョンでは観察されなかった振動が起こるのか?クモの巣解析してみると少し理解が深まる。x-y平面上に、差分方程式の左辺および右辺に相当する、\(y=x\)および\(y=ax(1-x)\)を描く。x軸上の点\((N_0, 0)\)から上方向に伸ばした垂線が\(y=ax(1-x)\)をに交わる点は\((N_0, N_1)\)である。

# Cobweb解析
# パラメタ
a<-3.2;
# 平衡点
N_<-1-1/a;
# くもの巣スタート
N0<- 0.3;  ## 初期値(色々な値を代入して遊んでみると良い)
# まずy=x, y=a*x(1-x)をプロットする
curve(a*x*(1-x), xlim=c(0, 1.1), ylim=c(0,1.1*0.5*0.5*a), xlab="Nt", ylab="Nt+1");
lines(c(0, 2*N_), c(0, 2*N_))  # 初期値からy=xに直線を引く
text(N0,0, "(N0, 0)", pos=4)   #  初期値のラベル
lines(c(N0,N0), c(0,N0))       #  上の点からy=a*x(1-x)に直線を引く
text(N0,a*N0*(1-N0), "(N0, N1)", pos=4)  # 次の点N_1のラベル
for(i in 1:20) {  ## 縦横20回クモの巣解析
    N1<- a*N0*(1-N0);
    lines( c(N0, N0), c(N0, N1) );
    lines(c(N0, N1), c(N1, N1) );
    N0<-N1;
}

\((N_0, N_1)\)からさらにx軸方向へ伸ばした直線が\(y=x\)と交わる点は\((N_1, N_1)\)である。\(y=ax(1-x)\)\(y=x\)に向かって次々と垂線、水平線を引き続けると、\((N_1, N_2)\)\((N_2, N_2)\)\((N_2, N_3)\)….と差分方程式の解をクモの巣状にたどることになる。\(y=ax(1-x)\)\(y=x\)と交わる点での傾きが-1よりも小さい(急である)ならば、クモの巣は段々と広がって、振動するようになるのだ。パラメタ\(a\)が4を超えると、放物線\(y=ax(1-x)\)の山は大きくなりすぎて、クモの巣は直ぐに正の領域を飛びぬけてしまう。すなわち人口爆発が起きて絶滅してしまう。差分方程式に強制的に当てはめる仮定で、「一つ前の世代が次の世代の数に影響する」、という時間遅れの効果を暗黙の内に差し込んでしまっている。時間遅れの効果は微分方程式であっても、人口の挙動を不安定化(振動したり、カオスになったり)させる。

人口動態の挙動変化は、分岐図(bifurcation diagram)を描いてみると視覚的に理解できる。分岐図は、\(a\)の値が0から4まで徐々に変化させた時(横軸)、人口が絶滅するか(ゼロ)、安定するか(定点)、振動するか(2点)、カオスか(模様)を連続的に表示する方法である。

#分岐図のコード

## aを0から4まで4/100刻みで変化させる
a<-seq(0, 4, length=100)
## シミュレーションを500回走らせた後の100回を記録する
x<-numeric(100)
## 結果の受け皿。各aに対して100マス確保した。
ax<-expand.grid(x, a)

## シミュレーションの実行
for(j in 1:length(a)) {
    n<-0.4;  #初期値
    for (i in 1:500) n=a[j]*n*(1-n)  # 安定するまで500世代回す
    for (i in 1:100) {               # 最後の100回を記録する
        n=a[j]*n*(1-n)
        ax[i+(j-1)*length(x),1]=n      # 受け皿に代入
    }
}

plot(ax[,2], ax[,1], pch=16, cex=0.2, xlab="a", ylab="500世代以降の人口")

\(0<a<1\)の時絶滅し、\(1<a<3\)の時、一定の人口に平衡する。徐々に安定平衡の人口は増加し、\(a>3\)のところで突然分岐する。2周期から4周期、8周期と分岐を繰り返し3.5を超えたあたりから不規則で周期性も無い複雑な挙動=カオスの状態になる。差分ロジスティック方程式は、完全に決定論的(確率シミュレーションではない)であるにもかかわらず、カオスの状態になった人口の挙動は、予測不可能である。カオスはホワイトノイズと異なり、ある一定の値の間に完全に収まる(この場合、0から1の間のある一定の範囲)。ホワイトノイズは増加か減少のどちらかの方向にドリフトしてゆく。またカオス状態では、極小の初期値の違いが数世代後には、非常に大きな違いを生み出す。